#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <iostream>

using namespace std;  
using namespace cv; 


void sharpenImage(const Mat & input, Mat & result );

int main(){

	Mat image, sharpen, filtered;

	image = imread("C:\\openCVImgs\\motor.jpg");
	if(!image.data){
		cout << "Cannot find image";
		getchar();
		return -1;
	}

	namedWindow("image");
	imshow("image", image);

	sharpenImage(image, sharpen);
	
	namedWindow("Sharpen");
	imshow("Sharpen", sharpen);


	Mat kernel = (Mat_<char>(3,3) <<	0,-1,0,
										-1,5,-1,
										0,-1,0
	);



	filter2D(sharpen,filtered,sharpen.depth(),kernel);
	
	namedWindow("filtered");
	imshow("filtered", filtered);

	waitKey(0);

	return 0;
}


void sharpenImage(const Mat & input, Mat & result ){

	result.create(input.size(), input.type());
	const int channels = input.channels();
	const int columns = channels * (input.cols-1);

	for(int row=1;row < input.rows - 1;row++){
		const uchar* prev = input.ptr<uchar>(row - 1);
		const uchar* curr = input.ptr<uchar>(row);
		const uchar* next = input.ptr<uchar>(row + 1);

		uchar* output = result.ptr<uchar>(row);

		for(int i = channels; i < columns;++i){
			*output++ = saturate_cast<uchar>(5*curr[i] - curr[i-channels] - curr[i+channels] - prev[i] - next[i]);
		}

	
		result.row(0).setTo(Scalar(0));
		result.row(result.rows-1).setTo(Scalar(0));
		result.col(0).setTo(Scalar(0));
		result.col(result.cols-1).setTo(Scalar(0));
	}
	
}